package com.example.netty.service;

import com.alibaba.fastjson.JSON;
import com.example.netty.common.Message;
import com.example.netty.constant.ResMessageType;
import com.example.netty.vo.Room;
import com.example.netty.vo.Shoe;
import com.example.netty.vo.User;
import io.netty.channel.Channel;
import io.netty.util.concurrent.ScheduledFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;

/**
 * 游戏仓库
 * @author zclever <304078606@qq.com>
 * @date 2021-03-02
 */
@Component
public class MatchService {

    private static final Logger logger = LoggerFactory.getLogger(MatchService.class);

    /** 匹配列表 */
    private final static ConcurrentLinkedQueue<User> userMatch = new ConcurrentLinkedQueue<>();

    private final static int BLOOD = 100;

    @Autowired
    private GameService gameService;

    @Autowired
    private RoomService roomService;

    private ScheduledFuture<?> future;

    private int matchCount;

    /**
     * 用户请求匹配
     * @param channel
     * @param content
     */
    public Message reqMatch(Channel channel, Object content) {
        logger.info("处理请求匹配");

        //取出用户id
        User user = gameService.getUserByChannel(channel);

        //处理匹配,取第一个用户,取3次,没有就把自己放入匹配队列
        User match = userMatch.poll();
        if(match==null){
            //没匹配到,把自己加入队列,返回匹配等待
            userMatch.add(user);

            //匹配十次不成功,把自己移除匹配队列,返回匹配失败
            matchCount = 3;
            future = channel.eventLoop().scheduleAtFixedRate(()->{
                timer(gameService,roomService,user);
            }, 0, 1, TimeUnit.SECONDS);

            logger.info("返回匹配等待");
            return new Message(ResMessageType.resMatchWait);
        }else{
            //匹配成功,通知双方,并进入房间
            Message message = new Message(ResMessageType.resMatchSuccess);
            logger.info("返回我方匹配成功");
            channel.writeAndFlush(message.toMsg());
            Channel ch = gameService.getChannelByUser(match);
            logger.info("返回对方匹配成功");
            ch.writeAndFlush(message.toMsg());

            //设置血量和分配给双方道具
            user.setBlood(BLOOD);
            match.setBlood(BLOOD);
            List shoeList = new ArrayList();
            for(int i=1;i<=5;i++){
                shoeList.add(new Shoe(i,"拖鞋"+i,10));
            }
            user.setShoeList(shoeList);
            match.setShoeList(shoeList);

            //返回创建房间成功
//            logger.info("返回我方创建房间成功");
            Message message1 = roomService.addRoom(channel, content);
//            channel.writeAndFlush(message1.toMsg());

            //取出房间,加入双方,并返回
            Room room = (Room) message1.getContent();
            roomService.inRoom(ch, "{\"roomId\":\""+room.getId()+"\"}");
            Message message2 = roomService.inRoom(channel, "{\"roomId\":\""+room.getId()+"\"}");

            //返回加入房间成功
            logger.info("返回我方加入房间成功");
            return message2;
        }
    }

    /**
     * 匹配10次取消
     * @param gameService
     * @param roomService
     * @param user
     */
    private void timer(GameService gameService,RoomService roomService,User user) {

        //如果匹配到了,结束匹配等待
        if(roomService.getRoomByUser(user)!=null){
            logger.info("匹配到了,结束匹配等待");
            future.cancel(false);
            return;
        }

        //如果匹配10次没匹配到,移除匹配队列,返回匹配失败,并结束匹配等待
        //匹配不到加入机器人,移除匹配队列,返回匹配成功
        if(matchCount--<=0){
//            logger.info("匹配10次没匹配到,移除匹配队列,返回匹配失败,并结束匹配等待");
            userMatch.remove(user);
//
            Channel channel = gameService.getChannelByUser(user);
//            Message message = new Message(ResMessageType.resMatchFail);
//            channel.writeAndFlush(message.toMsg());
            logger.info("匹配3次没匹配到,加入机器人");
            //匹配成功,通知双方,并进入房间
            Message message = new Message(ResMessageType.resMatchSuccess);

            logger.info("返回我方匹配成功");
            channel.writeAndFlush(message.toMsg());

            //设置我方血量
            user.setBlood(BLOOD);

            //添加机器人
            User robot = new User();
            robot.setId(0);
            robot.setName("机器人"+0);
            robot.setRoot(true);
            robot.setBlood(BLOOD);

            //分配给双方道具
            List shoeList = new ArrayList();
            for(int i=1;i<=5;i++){
                shoeList.add(new Shoe(i,"拖鞋"+i,10));
            }
            user.setShoeList(shoeList);
            robot.setShoeList(shoeList);

            //返回创建房间成功
//            logger.info("返回我方创建房间成功");
            Message message1 = roomService.addRoom(channel, null);
//            channel.writeAndFlush(message1.toMsg());

            //取出房间,加入双方,并返回
            Room room = (Room) message1.getContent();
            room.addUser(robot);
            Message message2 = roomService.inRoom(channel, "{\"roomId\":\""+room.getId()+"\"}");

            //返回加入房间成功
            logger.info("返回我方加入房间成功");
            channel.writeAndFlush(message2.toMsg());

            future.cancel(false);
        }else{
            logger.info("用户匹配中,等待{}秒",3-matchCount);
        }
    }

    /**
     * 用户取消匹配
     * @param channel
     * @param content
     */
    public Message cancelMatch(Channel channel, Object content) {
        logger.info("处理取消匹配");

        //取出用户id
        User user = gameService.getUserByChannel(channel);
        userMatch.remove(user);

        future.cancel(false);

        //返回取消成功
        logger.info("返回取消匹配");
        return new Message(ResMessageType.cancelMatch);
    }

    public void removeUserMatch(User user) {
        userMatch.remove(user);
    }
}
